#include <iostream>  
#include <sys/poll.h>  
#include <sys/socket.h>  
#include <netinet/in.h>  
#include <string.h>  
#include <unistd.h>  
  
const int MAX_EVENTS = 5;  
const int PORT = 8080;  
  
int main() {  
    int master_socket, addrlen, client_socket, activity, max_sd, new_socket, i, valread;  
    int client_socket_array[MAX_EVENTS] = {0};  
  
    // 创建 socket  
    if ((master_socket = socket(AF_INET, SOCK_STREAM, 0)) == 0) {  
        perror("socket failed");  
        exit(EXIT_FAILURE);  
    }  
  
    // 绑定到端口 8080  
    struct sockaddr_in address;  
    address.sin_family = AF_INET;  
    address.sin_addr.s_addr = INADDR_ANY;  
    address.sin_port = htons(PORT);  
  
    if (bind(master_socket, (struct sockaddr*)&address, sizeof(address)) < 0) {  
        perror("bind failed");  
        exit(EXIT_FAILURE);  
    }  
  
    // 监听  
    if (listen(master_socket, 3) < 0) {  
        perror("listen");  
        exit(EXIT_FAILURE);  
    }  
  
    // 设置 poll  
    struct pollfd fdarray[MAX_EVENTS];  
    int n = 0;  
  
    // 添加主 socket 到 poll 数组  
    fdarray[n].fd = master_socket;  
    fdarray[n].events = POLLIN;  
    memset(&(fdarray[n].revents), 0, sizeof(fdarray[n].revents));  
    n++;  
  
    while (1) {  
        // 等待事件  
        activity = poll(fdarray, n, -1);  
  
        if ((activity < 0) && (errno != EINTR)) {  
            perror("poll error");  
        }  
  
        // 遍历所有文件描述符  
        for (i = 0; i < n; i++) {  
            // 检查是否有新连接  
            if (fdarray[i].fd == master_socket) {  
                if (fdarray[i].revents & POLLIN) {  
                    addrlen = sizeof(address);  
                    client_socket = accept(master_socket, (struct sockaddr*)&address, (socklen_t*)&addrlen);  
  
                    std::cout << "New connection accepted, client_socket:" << client_socket <<  std::endl;  
  
                    // 添加新 socket 到 poll 数组  
                    fdarray[n].fd = client_socket;  
                    fdarray[n].events = POLLIN;  
                    memset(&(fdarray[n].revents), 0, sizeof(fdarray[n].revents));  
  
                    client_socket_array[n] = client_socket;  
                    n++;  
  
                    // 检查数组是否溢出  
                    if (n == MAX_EVENTS) {  
                        perror("Too many connections. Exiting...");  
                        exit(EXIT_FAILURE);  
                    }  
                }  
            } else {  
                // 检查客户端数据  
                if (fdarray[i].revents & POLLIN) {  
                    char buffer[1024] = {0};  
                    valread = read(fdarray[i].fd, buffer, 1024);  
  
                    if (valread == 0) {  
                        // 客户端断开连接  
                        std::cout << "Client " << fdarray[i].fd << " disconnected" << std::endl;  
  
                        close(client_socket_array[i]);  
                        client_socket_array[i] = 0;  
                    } else {  
                        // 接收客户端数据  
                        buffer[valread] = '\0';  
                        std::cout << "Received from client " << fdarray[i].fd << " : " << buffer << std::endl;  
                    }  
                }  
            }  
        }  
    }  
  
    return 0;  
}